package org.mipt.infsec.steganography.api.datastorage;

/**
 * Class describe bit - an element of information
 */
public class Bit
{
    private static final String UNIT = "1";
    private static final String ZERO = "0";
    private Boolean value;

    /**
     * Default constructor
     */
    public Bit()
    {
        this.value = true;
    }

    /**
     * Construct Bit from source Boolean
     * @param value source value
     */
    public Bit(Boolean value)
    {
        this.value = value;
    }

     /**
     * Construct Bit from source integer
     * @param value source value
     */
    public Bit(Integer value)
    {
        if (value == 1) this.value = true;
        if (value == 0) this.value = false;

        if (value != 1 && value != 0) throw new IllegalArgumentException("Incompativle type of input value: " + value);
    }

    /**
     * Construct Bit from source string
     * @param value source value
     */
    public Bit(String value)
    {
        if (value.equals(UNIT)) this.value = true;
        if (value.equals(ZERO)) this.value = false;
        if (!UNIT.equals(value) && !ZERO.equals(value)) throw new IllegalArgumentException("Incompativle type of input value: " + value);
    }

    /**
     * Function to convert byte to bits array
     * @param octet source byte value
     * @return Bit's array, which equal to source byte
     */
    public static Bit[] getBits(Byte octet)
    {
        Bit[] array = new Bit[8];
        int iteration = 0;
        while (octet > 0)
        {
            array[7 - iteration] = new Bit(octet % 2);
            octet =(byte) (octet / 2);
            iteration++;
        }
        while (iteration < 8)
        {
            array[7 - iteration] = new Bit(0);
            iteration++;
        }
        return array;
    }

    public boolean isUNIT()
    {
        return value;
    }

    public boolean isZERO()
    {
        return !value;
    }

    public String toString()
    {
        if (this.isUNIT()) return "1";
        else return "0";
    }

}
